package com.stox.navigator.ui.swing.view;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.List;

import javax.swing.JScrollPane;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import com.stox.charting.ui.swing.action.ReplaceChartAction;
import com.stox.core.event.ApplicationEventListener;
import com.stox.core.event.ApplicationEventPublisher;
import com.stox.core.event.ExchangeConfiguredEvent;
import com.stox.core.event.ScripAddedEvent;
import com.stox.core.manager.ExchangeManager;
import com.stox.core.manager.ScripManager;
import com.stox.core.model.Exchange;
import com.stox.core.model.Scrip;
import com.stox.core.model.intf.HasBars;
import com.stox.core.ui.swing.wrapper.JTree;
import com.stox.design.Callback;
import com.stox.ioc.Container;
import com.stox.navigator.ui.swing.event.NavigatorTreeMouseAdapter;
import com.stox.navigator.ui.swing.widget.AutoNavigationPanel;
import com.stox.resources.i18n.MessageSource;

public class ScripsPanel extends AbstractNavigatorTab {
	private static final long serialVersionUID = -2991903722464340263L;

	private ExchangeManager exchangeManager;
	private ScripManager scripManager;
	private ReplaceChartAction replaceChartAction;
	
	
	private JTree tree;
	private DefaultMutableTreeNode  root;
	
	@Override
	public int getOrder() {
		return 0;
	}
	
	@Override
	public String getName() {
		return MessageSource.getMessage("Scrips");
	}
	
	public ScripsPanel() {
		this.exchangeManager = Container.get(ExchangeManager.class);
		this.scripManager = Container.get(ScripManager.class);
		this.replaceChartAction = Container.get(ReplaceChartAction.class);
	}
	
	@Override
	public void keyReleased(KeyEvent e) {}
	@Override
	public void keyTyped(KeyEvent e) {}
	
	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == KeyEvent.VK_ENTER){
			ActionEvent event = new ActionEvent(tree, e.getID(), "");
			replaceChartAction.actionPerformed(event);
		}
	}	
	
	public void initializeInternal(){
		root = new DefaultMutableTreeNode(MessageSource.getMessage("Exchanges"));
		tree = new JTree(root);
		
		tree.addMouseListener(new NavigatorTreeMouseAdapter());
		tree.addKeyListener(this);
		JScrollPane scrollPane = new JScrollPane(tree);
	
		
		List<Exchange> exchanges = exchangeManager.getConfiguredExchanges();
		if(exchanges != null && !exchanges.isEmpty()){
			for(Exchange exchange : exchanges){
				root.add(createExchangeNode(exchange));
			}
		}
		ApplicationEventPublisher.subscribe(new ApplicationEventListener(){
			@Override
			public boolean supports(Class<?> clazz) {
				return clazz.isAssignableFrom(ExchangeConfiguredEvent.class);
			}
			@Override
			public void onApplicationEvent(Object object) {
				ExchangeConfiguredEvent event = (ExchangeConfiguredEvent)object;
				Exchange exchange = (Exchange)event.getSource();
				DefaultTreeModel dm = (DefaultTreeModel)tree.getModel();
				DefaultMutableTreeNode exchangeNode = createExchangeNode(exchange);
				dm.insertNodeInto(exchangeNode, root, root.getChildCount());
				tree.expandPath(new TreePath(dm.getPathToRoot(exchangeNode)));
			}
		});
		
		Callback<DefaultMutableTreeNode, Object> callback = 
				new Callback<DefaultMutableTreeNode, Object>(){
			@Override
			public Object execute(DefaultMutableTreeNode payload) {
				replaceChartAction.actionPerformed(new ActionEvent(tree, 0, ""));
				return null;
			}
		};
		add(new AutoNavigationPanel(this,HasBars.class,callback), BorderLayout.NORTH);
		add(scrollPane, BorderLayout.CENTER);
		DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
		DefaultMutableTreeNode node = (DefaultMutableTreeNode)treeModel.getRoot();
		DefaultMutableTreeNode targetNode = (DefaultMutableTreeNode)node.children().nextElement();
		TreePath path = new TreePath(treeModel.getPathToRoot(targetNode));
		tree.expandPath(path);
		tree.scrollPathToVisible(path);
		tree.setRootVisible(false);
	}
	
	private DefaultMutableTreeNode createExchangeNode(Exchange exchange){
		DefaultMutableTreeNode exchangeNode = new DefaultMutableTreeNode(exchange);
		final DefaultMutableTreeNode allNode = new DefaultMutableTreeNode(MessageSource.getMessage("All"));
		exchangeNode.add(allNode);
		DefaultMutableTreeNode indexNode = new DefaultMutableTreeNode(MessageSource.getMessage("Indices"));
		exchangeNode.add(indexNode);
		DefaultMutableTreeNode sectorNode = new DefaultMutableTreeNode(MessageSource.getMessage("Sectors"));
		exchangeNode.add(sectorNode);
	
		List<Scrip> scrips = scripManager.findByExchangeCode(exchange.getCode());
		if(scrips != null && !scrips.isEmpty()){
			for(Scrip scrip : scrips){
				allNode.add(new DefaultMutableTreeNode(scrip));
			}
		}
		
		ApplicationEventPublisher.subscribe(new ApplicationEventListener(){
			Class<?>[] classes = {ScripAddedEvent.class};
			@Override
			public boolean supports(Class<?> clazz) {
				for(Class<?> clazz1 : classes){
					if(clazz.isAssignableFrom(clazz1)){
						return true;
					}
				}
				return false;
			}
			@Override
			public void onApplicationEvent(Object event) {
				if(event instanceof ScripAddedEvent){
					ScripAddedEvent scripAddedEvent = (ScripAddedEvent)event;
					Scrip scrip = (Scrip)scripAddedEvent.getSource();
					if(!tree.containsChildWithUserObject(scrip, allNode)){
						DefaultTreeModel dm = (DefaultTreeModel)tree.getModel();
						DefaultMutableTreeNode scripNode = new DefaultMutableTreeNode(scrip); 
						dm.insertNodeInto(scripNode, allNode, 0);
						tree.expandPath(new TreePath(dm.getPathToRoot(scripNode)));
					}
				}
			}
		});
		return exchangeNode;
	}
	
	@Override
	public JTree get() {
		return tree;
	}
}
